package com.wallet.my.service.impl;

import com.wallet.my.dao.mapper.AccountMapper;
import com.wallet.my.dao.pojo.AccountDO;
import com.wallet.my.service.ImportAccountService;
import com.wallet.my.util.EthUtil;
import org.bitcoinj.wallet.UnreadableWalletException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.crypto.*;
import org.web3j.utils.Numeric;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

/**
 * 导入账号接口实现类
 **/
@Service
public class ImportAccountServiceImpl implements ImportAccountService {
    @Autowired
    private EthUtil ethUtil;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private AccountDO accountDO;
//私钥导入账号
    @Override
    public Map<String, Object> importAccountByPrivateKey(String privateKey, HttpSession session) {
        Credentials credentials = Credentials.create(privateKey);
        String publicKey = credentials.getEcKeyPair().getPublicKey().toString(16);
        String address = credentials.getAddress();
        HashMap<String, Object> map = new HashMap<>();
        map.put("address", address);
        map.put("publicKey", publicKey);
        String username = session.getAttribute("username").toString();
        String uuid = ethUtil.getUUID();
        accountDO.setId(uuid);
        accountDO.setAddress(address);
        accountDO.setBalance("0");
        accountDO.setUsername(username);
        accountDO.setAccountPath("");
        accountDO.setCreateMode("import-By-privateKey");
        accountMapper.addAccount(accountDO);
        return map;
    }

//密码和keystore导入账号
    @Override
    public Map<String, Object> importAccountByKeystore(String password, File keystore,HttpSession session) {
        Credentials credentials =null;
        try {
            credentials = Bip44WalletUtils.loadCredentials(password, keystore);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CipherException e) {
            e.printStackTrace();
        }
        String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16);
        String publicKey = credentials.getEcKeyPair().getPublicKey().toString(16);
        String address = credentials.getAddress();

        HashMap<String, Object> map = new HashMap<>();
        map.put("address", address);
        map.put("publicKey", publicKey);
        map.put("privateKey", privateKey);

        String username = session.getAttribute("username").toString();
        String uuid = ethUtil.getUUID();
        accountDO.setId(uuid);
        accountDO.setAddress(address);
        accountDO.setBalance("0");
        accountDO.setUsername(username);
        accountDO.setAccountPath("");
        accountDO.setCreateMode("import-By-keyStore");
        accountMapper.addAccount(accountDO);

        return map;
    }

////    助记词只导入一个根账户
//    public Map<String, Object> importRootByMnemonic(String mnemonic) {
//        Credentials credentials = Bip44WalletUtils.loadBip44Credentials("", mnemonic);
//        String privateKey = credentials.getEcKeyPair().getPrivateKey().toString(16);
//        String publicKey = credentials.getEcKeyPair().getPublicKey().toString(16);
//        String address = credentials.getAddress();
//        String balance = ethUtil.getMyBalance(web3j, address).toString();
//
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("address", address);
//        map.put("publicKey", publicKey);
//        map.put("privateKey", privateKey);
//
//        String uuid = ethUtil.getUUID();
//        accountDO.setId(uuid);
//        accountDO.setAddress(address);
//        accountDO.setBalance(balance);
//        accountMapper.addAccount(accountDO);
//        return map;
//    }

//    助记词导入指定账户地址M/44H/60H/0/0/i 的账户， 这里需要去数据库里加判断  这里比较复杂，还需要思考
    @Override
    public Map<String, Object> importAccountByMnemonic(String mnemonic,String accountPath,HttpSession session) {
        ECKeyPair childECKeyPair = null;
        try {
            childECKeyPair = ethUtil.getECKeyPairByMnemonic(mnemonic, accountPath);
        } catch (UnreadableWalletException e) {
            e.printStackTrace();
        }
        String privateKey = childECKeyPair.getPrivateKey().toString(16);
        String publicKey = childECKeyPair.getPublicKey().toString(16);
        String address = Numeric.prependHexPrefix(Keys.getAddress(childECKeyPair));
        HashMap<String, Object> map = new HashMap<>();
        map.put("address", address);
        map.put("publicKey", publicKey);
        map.put("privateKey", privateKey);
        map.put("accountPath",accountPath);

        String username = session.getAttribute("username").toString();
        String uuid = ethUtil.getUUID();
        accountDO.setId(uuid);
        accountDO.setAddress(address);
        accountDO.setBalance("0");
        accountDO.setUsername(username);
        accountDO.setAccountPath(accountPath);
        accountDO.setCreateMode("import-By-mnemonic");
        accountMapper.addAccount(accountDO);
        
        return map;
    }

//    根据分层的地址解锁账户
    @Override
    public Map<String, Object> unlockAccountByMnemonic(String mnemonic, String accountPath, HttpSession session) {
        String username = session.getAttribute("username").toString();
        HashMap<String, Object> map = new HashMap<>();
        AccountDO accountPathByName = accountMapper.getAccountPathByName(accountPath, username);
        if(accountPathByName==null){
            map.put("privateKey", "账户地址输入错误，请检查后重新输入解锁");
            map.put("accountPath","错误："+accountPath);
        }else {
            ECKeyPair childECKeyPair = null;
            try {
                childECKeyPair = ethUtil.getECKeyPairByMnemonic(mnemonic, accountPath);
            } catch (UnreadableWalletException e) {
                e.printStackTrace();
            }
            String privateKey = childECKeyPair.getPrivateKey().toString(16);
            String publicKey = childECKeyPair.getPublicKey().toString(16);
            String address = Numeric.prependHexPrefix(Keys.getAddress(childECKeyPair));
            map.put("address", address+"--请核对地址是否一致");
            map.put("publicKey", publicKey);
            map.put("privateKey", privateKey);
            map.put("accountPath",accountPath);
        }
        return map;
    }
}
